home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 31 / Amiga Format CD31 (1998-09-02)(Future Publishing)(GB)(Track 1 of 2)[!][issue 1998-10].iso / -seriously_amiga- / hardware / transadf / source / gzip.c < prev    next >
C/C++ Source or Header  |  1998-07-20  |  5KB  |  196 lines

  1. /* gzip.c - Handle all GZip-file specific tasks
  2. ** Copyright (C) 1997,1998 Karl J. Ots
  3. ** 
  4. ** This program is free software; you can redistribute it and/or modify
  5. ** it under the terms of the GNU General Public License as published by
  6. ** the Free Software Foundation; either version 2 of the License, or
  7. ** (at your option) any later version.
  8. ** 
  9. ** This program is distributed in the hope that it will be useful,
  10. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. ** GNU General Public License for more details.
  13. ** 
  14. ** You should have received a copy of the GNU General Public License
  15. ** along with this program; if not, write to the Free Software
  16. ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  17. */
  18.  
  19. /*--------------------*/
  20. /* GZip file routines */
  21. /*--------------------*/
  22.  
  23. #include <exec/types.h>
  24. #include <dos/dos.h>
  25. #include <clib/dos_protos.h>
  26.  
  27. #include <string.h>
  28.  
  29. #include "gzip.h"
  30. #include "main.h"
  31. #include "util.h"
  32. #include "errors.h"
  33.  
  34.  
  35. /*-----------------------*/
  36. /* Structures and macros */
  37. /*-----------------------*/
  38.  
  39. struct GZHead {
  40.   UWORD  MagicNum;
  41.   UBYTE  CMethod;    
  42.   UBYTE  Flags;
  43.   ULONG  Date;
  44.   UBYTE  EFlags;
  45.   UBYTE  OS;
  46. }; /* sizeof = 10 */
  47.  
  48. struct GZTail {
  49.   ULONG  CRC;
  50.   ULONG  USize;
  51. };
  52.  
  53. #define GZ_MAGNUM    0x1F8B
  54.  
  55. /* Flags */
  56. #define GZ_FTEXT     0x01  /* Bit 0           */
  57. #define GZ_FHCRC     0x02  /* Bit 1           */
  58. #define GZ_FEXTRA    0x04  /* Bit 2           */
  59. #define GZ_FNAME     0x08  /* Bit 3           */
  60. #define GZ_FCOMMENT  0x10  /* Bit 4           */
  61. #define GZ_RESERVED  0xE0  /* Bits 5, 6 and 7 */
  62.  
  63.  
  64. /* 
  65. ** Output a GZip Header to the specified file.
  66. ** Return TRUE if no errors. else FALSE.
  67. */
  68. BOOL writeGZHead (BPTR outFile, STRPTR origName)
  69. {
  70.   UWORD nlen;
  71.   struct GZHead gzHead = {GZ_MAGNUM,  /* GZip Magic Number.       */
  72.                           8,          /* Method - deflate.        */
  73.                           0,          /* Flags (to be filled in). */
  74.                           0,          /* Date  (to be filled in). */
  75.                           0,          /* Extra flags.             */
  76.                           1};         /* OS Code (1 = Amiga)      */
  77.   
  78.   /* Fill in the flags */
  79.   if (origName)
  80.     gzHead.Flags |= GZ_FNAME;  /* Original name supplied */
  81.   
  82.   /* Fill in the date (little endian) */
  83.   gzHead.Date = LEL (unixDate ());
  84.   
  85.   /* Write the header to the file */
  86.   if ( Write (outFile, &gzHead, 10) != 10) return FALSE;
  87.   
  88.   /* Write extra data if applicable */
  89.   if (origName)
  90.   {
  91.     nlen = strlen (origName) + 1;
  92.     if ( Write (outFile, origName, nlen) != nlen) return FALSE;
  93.   }
  94.   
  95.   /* Header written sucessfully */
  96.   return TRUE;
  97. }
  98.  
  99.  
  100. /*
  101. ** Finish writing a GZip file.
  102. ** Return TRUE if no errors. else FALSE.
  103. */
  104. BOOL finishGZFile (BPTR outFile, ULONG CRC, ULONG USize)
  105. {
  106.   struct GZTail gzTail;
  107.   
  108.   gzTail.CRC   = LEL (CRC);
  109.   gzTail.USize = LEL (USize);
  110.   
  111.   if ( Write (outFile, &gzTail, 8) != 8) return FALSE;
  112.   
  113.   return TRUE;
  114. }
  115.  
  116.  
  117. /*
  118. ** Skip the GZip Header of a specified file.
  119. ** Return TRUE if no errors. else FALSE.
  120. */
  121. BOOL skipGZHead (BPTR inFile)
  122. {
  123.   struct GZHead gzHead;
  124.   UBYTE Char, Flags;
  125.   UWORD ESize;
  126.   
  127.   /* Read in the header */
  128.   if ( Read (inFile, &gzHead, 10) != 10) return FALSE;
  129.   
  130.   /* Check the compression method and the reserved flags   */
  131.   /* (We assume the magic number has already been checked) */
  132.   if (gzHead.CMethod != 8)
  133.   {
  134.     FPrintf (StdErr,
  135.              "%s: Error - Only Deflate compression method supported.\n",
  136.              ProgName);
  137.     cleanExit (RETURN_ERROR, NULL);
  138.   }
  139.   
  140.   Flags = gzHead.Flags;
  141.   if (Flags & GZ_RESERVED)
  142.   {
  143.     FPrintf (StdErr,
  144.              "%s: Warning - Reserved flags set, decompression may fail.\n",
  145.              ProgName);
  146.   }
  147.   
  148.   /* Skip the rest of the header depending on the flags */
  149.   
  150.   if (Flags & GZ_FEXTRA)  /* Extra field */
  151.   {
  152.     if ( Read (inFile, &ESize, 2) != 2) return FALSE;
  153.     ESize = LES (ESize);
  154.     Seek (inFile, ESize, OFFSET_CURRENT);
  155.   }
  156.   
  157.   if (Flags & GZ_FNAME)  /* File Name */
  158.   {
  159.     Char = 1;
  160.     while (Char)
  161.       if (Read (inFile, &Char, 1) != 1) return FALSE;      
  162.   }
  163.   
  164.   if (Flags & GZ_FCOMMENT)  /* File Comment */
  165.   {
  166.     Char = 1;
  167.     while (Char)
  168.       if (Read (inFile, &Char, 1) != 1) return FALSE;      
  169.   }
  170.   
  171.   if (Flags & GZ_FHCRC)  /* Header CRC */
  172.     Seek (inFile, 2, OFFSET_CURRENT);
  173.   
  174.   /* inFile is now at compressed data */
  175.   return TRUE;
  176. }
  177.  
  178.  
  179. /*
  180. ** Read the end of a GZip file and return the CRC
  181. ** and USize in supplied arrays.
  182. ** Return TRUE if no errors, else FALSE.
  183. */
  184. BOOL readGZTail (BPTR inFile, ULONG *CRC, ULONG *USize)
  185. {
  186.   struct GZTail gzTail;
  187.   
  188.   Seek (inFile, -8, OFFSET_END);
  189.   if ( Read (inFile, &gzTail, 8) != 8) return FALSE;
  190.   
  191.   *CRC   = LEL (gzTail.CRC);
  192.   *USize = LEL (gzTail.USize);
  193.   
  194.   return TRUE;
  195. }
  196.